home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
maximus
/
aselect.zip
/
MSELECT.MEX
< prev
next >
Wrap
Text File
|
1996-05-25
|
12KB
|
430 lines
// ----------------------------------------------------------------------
//
// Area Selector v0.1 beta
//
// Copyright 1996 by Brian C. Lane
//
// All Rights Reserver
// This code may not be modified and used in any other piece of code
// without acknowledging the source (me!)
//
//-----------------------------------------------------------------------
//
// This code is a work in progress. It currently is only useful on the
// message bases, the next version will also work on file bases.
//
// Probably the only thing you will want to change are the colors,
// defined directly below as GC_*, see MAX.DOC for info on how to set
// the AVATAR colors.
//
// ---------------------------------------------------------------------
// INSTALL:
// You've obviously unpacked the archive, so put mselect.mex and
// xgetch.mh in your /max/m subdirectory. Run MEX on it:
// MEX mselect
//
// Change your Message Area change command to look like so:
// MEX M/mselect Demoted "Area change"
//
// Don't forget to comment out the old Area change line.
// Now when your users select 'A'rea change from the message menu
// they will be presented with a user friendly interface!
//
// ---------------------------------------------------------------------
//
// This allows a user to walk up and down the areas available on the
// system and to select one to read by hitting enter. It checks the
// user's video type and uses the default(ugly) message selection if
// ANSI isn't supported.
//
// ----------------------------------------------------------------------
#include <max.mh>
#include <prm.mh>
#include <xgetch.mh> // Use xgetch routine
// ----------------------------------------------------------------------
// Color definitions
// ----------------------------------------------------------------------
#define GC_TITLE_BBS "\x16\x01\x79"
#define GC_TITLE_USER "\x16\x01\x7e"
#define GC_HELP COL_GRAY
#define GC_NUM COL_WHITE
#define GC_UNREAD COL_LGREEN
#define GC_NAME COL_WHITE
#define GC_DESC COL_LBLUE
#define GC_NUM_HI "\x16\x01\x78"
#define GC_UNREAD_HI "\x16\x01\x7A"
#define GC_NAME_HI "\x16\x01\x78"
#define GC_DESC_HI "\x16\x01\x79"
#define ATYPE msg
#define AREAT _marea
#define ARVAR marea
#define AreaFindFirst msgareafindfirst
#define AreaFindNext msgareafindnext
#define AreaFindPrev msgareafindprev
#define AreaFindClose msgareafindclose
#define AreaSelect msgareaselect
//========================= Page structure =================================
// Lastfile: This integer defines the last file on this page, in most cases
// this should equal to 16, except for the last page
// Filename: Contains the filename, BUT! if filename="", <desc> contains
// a description that is continued from the last file.
// And, if filename="z", <desc> is a comment.
// Size: Size of the file
// Date: Date of file as a string
// Desc: Description or comment
// Tagged: TRUE if file is tagged and FALSE if not
struct _page
{
string: name;
long: num;
long: current;
long: high;
string: desc;
int: tagged;
} ;
array [1..20] of struct _page: page;
int: lastgroup; // Lastgroup on the page
int: pos; // Position 1..18
int: errwin; // Indicates if line 25 needs clearing
string: last; // Last area selected by the user
// --------------------------------------------------------------------
// Fill in the page structure with the next 18 groups, starting with
// The next group after the one in page[18].name, unless it is null,
// then start with the top
// --------------------------------------------------------------------
int next_group_page()
{
int: i, x;
struct AREAT: a;
if ( lastgroup = 0 )
{
i:=AreaFindFirst(a, "", AFFO_NODIV);
if( i = 0 )
{
return -1;
}
} else {
i:=AreaFindFirst(a, page[lastgroup].name, AFFO_NODIV);
if( i = 0 )
{
return -2;
}
i:=AreaFindNext(a);
if( i = 0 )
{
return -3;
}
}
print( AVATAR_GOTO, (char)25, (char)1);
print( COL_WHITE, "Scanning group ");
x := 1;
while( ( x < 19 ) and i )
{
print( AVATAR_GOTO, (char)25, (char)16 );
print( x );
i := AreaSelect( a.name );
page[x].name := a.name;
page[x].desc := substr( a.descript, 1, 40);
page[x].num := ATYPE.num;
page[x].current := ATYPE.current;
page[x].high := ATYPE.high;
i:=AreaFindFirst(a, a.name, AFFO_NODIV);
i:=AreaFindNext(a);
if( i )
x := x + 1;
}
AreaFindClose();
if ( i )
lastgroup := x-1;
else
lastgroup := x;
}
// ----------------------------------------------------------------------
// Fill in the page structure with the previous 18 groups, starting with
// The previous group before the one in page[1].name, unless it is null,
// then don't do anything.
// ----------------------------------------------------------------------
int prev_group_page()
{
int: i, x;
struct AREAT: a;
i:=AreaFindFirst(a, page[1].name, AFFO_NODIV);
if( i = 0 )
{
return -1;
}
i:=AreaFindPrev(a);
if( i = 0 )
{
return -2;
}
print( AVATAR_GOTO, (char)25, (char)1);
print( COL_WHITE, "Scanning group ");
x := 18;
while( ( x > 0 ) and i )
{
print( AVATAR_GOTO, (char)25, (char)16 );
print( strpadleft( itostr( x ), 2, ' ') );
i := AreaSelect( a.name );
page[x].name := a.name;
page[x].desc := substr( a.descript, 1, 40);
page[x].num := ATYPE.num;
page[x].current := ATYPE.current;
page[x].high := ATYPE.high;
i:=AreaFindFirst(a, a.name, AFFO_NODIV);
i:=AreaFindPrev(a);
if( i )
x := x - 1;
}
AreaFindClose();
lastgroup := 18;
}
// ----------------------------------------------------------------------
// Update the display with the current page information
//
// Shows the title bar with the BBS name and ??
// Shows the help bar at the bottom of the screen
//
// Shows 18 groups in format:
// # [unread msgs] name description
//
// ----------------------------------------------------------------------
int show_group_page()
{
int: x;
int: unread;
print( AVATAR_CLS );
print( GC_TITLE_BBS, " ", strpad( prm_string(PRM_SYSNAME), 38, ' ' ), GC_TITLE_USER, strpadleft( usr.name, 38, ' ' ), " " );
for( x := 1; x <= lastgroup; x := x + 1 )
{
print( AVATAR_GOTO, (char)(x+2), (char)2 );
unread := page[x].high - page[x].current;
print( GC_NUM, strpadleft( itostr(x), 3, ' '), GC_UNREAD, strpadleft( itostr(unread), 3, ' '), " ", GC_NAME, strpad( page[x].name, 30, ' '), GC_DESC, page[x].desc);
}
print( AVATAR_GOTO, (char)22, (char)12 );
print( GC_HELP, "[arrows] = select [enter] = read [Q] = Quit" );
// Return cursor to an out of the way place
print( AVATAR_GOTO, (char)1, (char)1 );
return 0;
}
// --------------------------------------------------------------------
// Hilight one line in the list of groups
// --------------------------------------------------------------------
int hilight_group( int: x )
{
int: unread;
print( AVATAR_GOTO, (char)(x+2), (char)1 );
unread := page[x].high - page[x].current;
print( GC_NUM_HI, " ", strpadleft( itostr(x), 3, ' '), GC_UNREAD_HI, strpadleft( itostr(unread), 3, ' '), " ", GC_NAME_HI, strpad( page[x].name, 30, ' '), GC_DESC_HI, strpad( page[x].desc, 41, ' ') );
print( AVATAR_GOTO, (char)(x+2), (char)1 );
}
// --------------------------------------------------------------------
// Un-Hilight one line in the list of groups
// --------------------------------------------------------------------
int unhilight_group( int: x )
{
int: unread;
print( AVATAR_GOTO, (char)(x+2), (char)1 );
unread := page[x].high - page[x].current;
print( GC_NUM, " ", strpadleft( itostr(x), 3, ' '), GC_UNREAD, strpadleft( itostr(unread), 3, ' '), " ", GC_NAME, strpad( page[x].name, 30, ' '), GC_DESC, strpad( page[x].desc, 41, ' ') );
print( AVATAR_GOTO, (char)(x+2), (char)1 );
}
// --------------------------------------------------------------------
// Handle keypresses in the group window
// --------------------------------------------------------------------
int group_key( int: k )
{
// Clear the error window
if( errwin = 1 )
{
print( AVATAR_GOTO, (char)25, (char)1 );
print( strpad( " ", 20, ' ' ) );
errwin := 0;
}
if( k = X_UP )
{
// If not at top of page, move up 1
if( pos > 1 )
{
unhilight_group( pos );
pos := pos - 1;
hilight_group( pos );
} else {
// Move up a page
prev_group_page();
pos := 18;
show_group_page();
hilight_group( pos );
}
}
if( k = X_PAGEUP )
{
// Move up a page
prev_group_page();
pos := 18;
show_group_page();
hilight_group( pos );
}
if( k = X_DOWN )
{
// If not at end of page move down 1
if( pos < lastgroup )
{
unhilight_group( pos );
pos := pos + 1;
hilight_group( pos );
} else if( lastgroup = 18 ) {
// Move down a page
next_group_page();
pos := 1;
show_group_page();
hilight_group( pos );
}
}
if( k = X_PAGEDOWN )
{
// Move up a page
next_group_page();
pos := 1;
show_group_page();
hilight_group( pos );
}
}
// --------------------------------------------------------------------
// Show a display of 1-16 groups. Keep a list of their names and
// info in a 16 entry array (read/unread, name, description)
// --------------------------------------------------------------------
int main()
{
int: stat, key, state;
char: nonstop;
lastgroup := 0; // Start at top
// Check user's video state and call normal routine if ANSI not supported
if( usr.video < VIDEO_ANSI )
{
msg_area();
return 0;
}
print(AVATAR_CLS);
last := ARVAR.name; // Remember the last area
if( ( stat := next_group_page() ) < 0 )
{
print("Error:" + itostr(stat) + " Getting first page\n");
return -1;
}
// Show the first page of groups
stat := show_group_page();
pos := 1;
hilight_group( pos );
state := 0;
while( stat = 0 )
{
key := xgetch();
if( key = 'Q' or key = 'q' )
{
stat := AreaSelect( last );
stat := 1;
} else {
if( state = 0 )
{
if( key = 0 )
key := xgetch();
// ENTER was hit, select the area
if( key = 0x0D )
{
stat := AreaSelect( page[pos].name );
// check for an error
if( stat = 0 )
{
print( AVATAR_GOTO, (char)25, (char)1 );
print( COL_LRED, "Error opening area ", page[pos].name );
errwin := 1;
} else {
stat := 1;
}
} else {
stat := group_key( key );
}
} else if( state = 1 ) {
// stat := thread_key( key );
}
}
}
print( AVATAR_CLS );
return 0;
}